package org.oproject.rmi.hessian.core.service.loader;

import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.oproject.rmi.hessian.core.logger.LogFactory;
import org.oproject.rmi.hessian.core.logger.Logger;
import org.oproject.rmi.hessian.core.service.ServiceInfo;

/**
 * @see
 * @author shenqing
 * @since 1.0
 * @version 1.0, Nov 16, 2010 11:07:00 AM
 */
public class XMLServiceLoader extends ServiceLoader
{
	private static Logger log = LogFactory.getLogger(XMLServiceLoader.class);
	
	private static final String FileName = "services-hessian.xml";
	
	@Override
	protected Set<ServiceInfo> load()
	{
		log.info("<-- 通过 [XMLServiceLoader] 加载服务接口 -->");
		Set<ServiceInfo> serviceInfos = new HashSet<ServiceInfo>();
		
		SAXReader reader = new SAXReader();
		
		InputStream xmlStream = this.getClass().getResourceAsStream("/" + FileName);
		
		if (null != xmlStream)
		{
			try
			{
				Document document = reader.read(xmlStream);
				Element root = document.getRootElement();

				if (null == root)
				{
					return null;
				}
				
				for(Object objService : root.elements())
				{
					if(null == objService || !(objService instanceof Element))
					{
						continue;
					}
					
					ServiceInfo serviceInfo = new ServiceInfo();
					serviceInfo = parserServiceInfo((Element)objService);
					
					if(null != serviceInfo && serviceInfo.validate())
					{
						serviceInfos.add(serviceInfo);
					}
				}
			}
			catch (DocumentException e)
			{
				e.printStackTrace();
			}
		}

		return serviceInfos;
	}

	/**
	 * 将xml中的一个节点，解析为serviceinfo对象
	 * @param service
	 * @return
	 */
	private ServiceInfo parserServiceInfo(Element service)
	{
		if(null == service || !service.getName().equals("service"))
		{
			return null;
		}
		
		ServiceInfo serviceInfo = new ServiceInfo();
		
		String name = service.attributeValue("id");
		if (null != name && !name.trim().equals(""))
		{
			serviceInfo.setName(name);
		}
		
		for(Object objProperty : service.elements())
		{
			if(null == objProperty || !(objProperty instanceof Element)
					|| !((Element)objProperty).getName().equals("property"))
			{
				continue;
			}
			
			Element property = (Element)objProperty;
			String propertyName = property.attributeValue("name");
			String propertyValue = property.attributeValue("value");
	
			if (null != propertyName && !propertyName.trim().equals("")
					&& null != propertyValue && !propertyValue.trim().equals(""))
			{
				if (propertyName.equals("serviceType"))
				{
					serviceInfo.setServiceType(propertyValue);
				}
				else if (propertyName.equals("methodName"))
				{
					serviceInfo.setMethodName(propertyValue);
				}
				else if (propertyName.equals("isSingle"))
				{
					serviceInfo.setSingle(propertyValue);
				}
				else if (propertyName.equals("classFullName"))
				{
					serviceInfo.setMethodName(propertyValue);
				}
			}
		}
		
		return serviceInfo;
	}
}
